package com.lsq.baseadmin.modules.controller;


import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.lsq.baseadmin.common.enums.SwitchEnum;
import com.lsq.baseadmin.common.exception.MyException;
import com.lsq.baseadmin.common.utils.AliyunOssUtil;
import com.lsq.baseadmin.common.utils.EnumUtil;
import com.lsq.baseadmin.common.utils.RsaEncryptUtil;
import com.lsq.baseadmin.modules.maintenance.entity.Menu;
import com.lsq.baseadmin.modules.maintenance.service.MenuService;
import com.lsq.baseadmin.modules.manage.entity.*;
import com.lsq.baseadmin.modules.manage.service.*;
import com.lsq.baseadmin.modules.manage.utils.AuthUtil;
import com.lsq.baseadmin.modules.manage.utils.MenuTreeUtil;
import com.lsq.baseadmin.modules.manage.vo.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 * 登录就能访问的controller
 * </p>
 *
 * @author lsq
 * @since 2020-10-22
 */
@Api(tags = "已登录开放的接口")
@RestController
@RequestMapping("/sys")
public class SystemController {

    @Value("${rsa.private-key}")
    private String privateKey;

    private MenuService menuService;
    private PositionService positionService;
    private RoleService roleService;
    private UserService userService;
    private DepartmentService departmentService;

    public SystemController(MenuService menuService, PositionService positionService, RoleService roleService, UserService userService, DepartmentService departmentService) {
        this.menuService = menuService;
        this.positionService = positionService;
        this.roleService = roleService;
        this.userService = userService;
        this.departmentService = departmentService;
    }

    /**
     *  获取职位列表  下拉选项用
     */
    @ApiOperation("职位列表")
    @GetMapping("/positionList")
    public ResponseEntity positionList() {
        QueryWrapper<Position> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name");
        wrapper.eq("status", SwitchEnum.ENABLE.getValue());
        List<Position> list = positionService.list(wrapper);
        return ResponseEntity.ok(list);
    }
    /**
     *  获取角色列表  下拉选项用
     */
    @ApiOperation("角色列表")
    @GetMapping("/roleList")
    public ResponseEntity roleList() {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name");
        List<Role> list = roleService.list(wrapper);
        return ResponseEntity.ok(list);
    }
    /**
     *  获取从库角色列表 测试用
     */
    @ApiOperation("角色列表从库")
    @GetMapping("/roleListSlave")
    public ResponseEntity roleListSlave() {
        List<Role> list = roleService.listSlave(null);
        return ResponseEntity.ok(list);
    }

    /**
     *  获取菜单列表  下拉选项用
     */
    @ApiOperation("菜单列表")
    @GetMapping("/menuList")
    public ResponseEntity menuList() {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name", "parent_id");
        List<Menu> list = menuService.list(wrapper);
        return ResponseEntity.ok(list);
    }

    /**
     *  获取部门列表  下拉选项用
     */
    @ApiOperation("部门列表")
    @GetMapping("/departmentList")
    public ResponseEntity departmentList() {
        QueryWrapper<Department> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name", "parent_id");
        wrapper.eq("status", SwitchEnum.ENABLE.getValue());
        List<Department> list = departmentService.list(wrapper);
        return ResponseEntity.ok(list);
    }

    /**
     *  获取我的菜单
     */
    @ApiOperation("我的树形菜单")
    @GetMapping("/myMenuTree")
    public ResponseEntity myMenuTree(HttpSession session) {
        List<Menu> list = AuthUtil.getLoginUser(session).getMyMenus();
        return ResponseEntity.ok(MenuTreeUtil.buildTree(list));
    }
    /**
     *  获取我的菜单
     */
    @ApiOperation("我的菜单")
    @GetMapping("/myMenu")
    public ResponseEntity myMenu(HttpSession session) {
        List<Menu> list = AuthUtil.getLoginUser(session).getMyMenus();
        return ResponseEntity.ok(list);
    }
    /**
     *  获取我的信息
     */
    @ApiOperation("我的信息")
    @GetMapping("/myInfo")
    public ResponseEntity myInfo(HttpSession session) {
        UserVo loginUser = AuthUtil.getLoginUser(session);
        User user = userService.getById(loginUser.getUser().getId());
        return ResponseEntity.ok(user);
    }
    /**
     *  更新枚举js
     */
    @GetMapping("/updateEnumJs")
    public ResponseEntity updatePublicEnumJs() {
        try {
            EnumUtil.updateEnum();
        } catch (IOException e) {
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity(HttpStatus.OK);
    }
    /**
     *  刷新我的菜单权限
     */
    @ApiOperation("刷新我的菜单权限")
    @GetMapping("/refreshMyMenu")
    public ResponseEntity refreshMyMenu(HttpSession session) {
        UserVo loginUser = AuthUtil.getLoginUser(session);
        List<Menu> menus = menuService.myMenus(loginUser.getUser().getId());
        loginUser.setMyMenus(menus);

        AuthUtil.setLoginUser(loginUser, session);
        return ResponseEntity.ok(menus);
    }
    /**
     *  上传头像
     */
    @ApiOperation("上传头像")
    @PostMapping("/uploadProfilePicture")
    public String upload(MultipartFile file){
        int error = 0;
        String url = null;
        try {
            String dir = "profilePicture";
            url = AliyunOssUtil.upload(file, dir);
        } catch (IOException e) {
            error = 1;
        }
        JsonObject obj = new JsonObject();
        obj.addProperty("error", error);
        obj.addProperty("url", url);
        return new Gson().toJson(obj);
    }

    /**
     * 修改个人资料
     * @param user User
     * @return ResponseEntity
     */
    @ApiOperation("修改个人资料")
    @PostMapping("/updateMyInfo")
    public ResponseEntity updateMyInfo(@RequestBody User user, HttpSession session) {
        UserVo loginUser = AuthUtil.getLoginUser(session);
        User newUser = new User();
        newUser.setId(loginUser.getUser().getId());
        newUser.setNickName(user.getNickName());
        newUser.setPhone(user.getPhone());
        newUser.setEmail(user.getEmail());
        newUser.setProfilePictureUrl(user.getProfilePictureUrl());
        newUser.setGender(user.getGender());
        userService.updateById(newUser);
        return new ResponseEntity(HttpStatus.OK);
    }

    /**
     * 修改密码
     * @param originalPassword 原密码
     * @param newPassword 新密码
     * @return ResponseEntity
     */
    @PostMapping("/updatePassword")
    public ResponseEntity updatePassword(@RequestParam("originalPassword") String originalPassword, @RequestParam("newPassword") String newPassword, HttpSession session) {
        UserVo loginUser = AuthUtil.getLoginUser(session);
        Integer loginUserId = loginUser.getUser().getId();
        try {
            // 解密前端传过来的原密码
            originalPassword = AuthUtil.convertPassword(originalPassword);
            originalPassword = RsaEncryptUtil.decrypt(originalPassword, privateKey);


            // 解密前端传过来的新密码
            newPassword = AuthUtil.convertPassword(newPassword);
            newPassword = RsaEncryptUtil.decrypt(newPassword, privateKey);
        } catch (Exception e) {
            throw new MyException(HttpStatus.PRECONDITION_FAILED, "非法请求！");
        }

        User user = userService.getById(loginUserId);
        // 解密的原密码跟数据库密码对比
        boolean matches = BCrypt.checkpw(originalPassword, user.getPassword());
        if (!matches) {
            throw new MyException(HttpStatus.PRECONDITION_FAILED, "原密码不正确！");
        }

        // 加密新密码
        newPassword = BCrypt.hashpw(newPassword, BCrypt.gensalt());

        User newUser = new User();
        newUser.setId(loginUserId);
        newUser.setPassword(newPassword);
        userService.updateById(newUser);
        return new ResponseEntity(HttpStatus.OK);
    }

}
